package com.mars.common.util;

import com.mars.common.constant.Constant;
import com.mars.common.base.UserContextInfo;
import com.mars.common.enums.HttpCodeEnum;
import com.mars.framework.exception.UnAuthException;
import com.mars.framework.redis.RedisCache;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import java.util.Base64;
import java.util.Optional;

/**
 * @author 程序员Mars
 */
@Component
@AllArgsConstructor
public class TokenUtils {

    private final RedisCache redisCache;

    /**
     * 创建token
     *
     * @param id id
     * @return String
     */
    public String createToken(Long id, String userName, String realName) {
        UserContextInfo userContextInfo = new UserContextInfo();
        userContextInfo.setId(id);
        userContextInfo.setUserName(userName);
        userContextInfo.setRealName(realName);
        userContextInfo.setTimestamp(System.currentTimeMillis());
        return Base64.getEncoder().encodeToString(JsonUtils.toJsonString(userContextInfo).getBytes());
    }


    /**
     * 获取用户ID
     *
     * @param request request
     * @return Long
     */
    public UserContextInfo getUserInfo(HttpServletRequest request) {
        try {
            String token = Optional.ofNullable(request.getHeader(Constant.TOKEN))
                    .orElse((String) request.getAttribute(Constant.TOKEN));
            if (StringUtils.isEmpty(token)) {
                throw new UnAuthException(HttpCodeEnum.TOKEN_INVALID.getCode(), "访问令牌为空");
            }
            token = token.split(" ")[1];
            UserContextInfo userContextInfo = JsonUtils.toBean(new String(Base64.getDecoder().decode(token)), UserContextInfo.class);
            if (StringUtils.isEmpty(token)) {
                throw new UnAuthException("访问令牌为空");
            }
            // 校验令牌有效期
            String cacheToken = redisCache.getCacheObject(Constant.USER_TOKEN_CACHE + userContextInfo.getId());
            if (StringUtil.isEmpty(cacheToken)) {
                throw new UnAuthException(HttpCodeEnum.TOKEN_INVALID.getCode(), "当前登录已过期");
            }
            return userContextInfo;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取用户ID
     *
     * @param request request
     * @return Long
     */
    public Long getUserId(HttpServletRequest request) {
        try {
            String token = request.getHeader(Constant.TOKEN);
            if (StringUtils.isEmpty(token)) {
                throw new UnAuthException(HttpCodeEnum.TOKEN_INVALID.getCode(), "访问令牌为空");
            }
            token = token.split(" ")[1];
            UserContextInfo userContextInfo = JsonUtils.toBean(new String(Base64.getDecoder().decode(token)), UserContextInfo.class);
            if (StringUtils.isEmpty(token)) {
                throw new UnAuthException(HttpCodeEnum.TOKEN_INVALID.getCode(), "访问令牌为空");
            }
            // 校验令牌有效期
            String cacheToken = redisCache.getCacheObject(Constant.USER_TOKEN_CACHE + userContextInfo.getId());
            if (StringUtil.isEmpty(cacheToken)) {
                throw new UnAuthException(HttpCodeEnum.TOKEN_INVALID.getCode(), "当前登录已过期");
            }
            return userContextInfo.getId();
        } catch (Exception e) {
            return null;
        }
    }
}
